/***************************************************************************
 *   This is a part of the NextCAD Web APP.                                *
 *   Copyright (C) AMCAX, All rights reserved.                             *
 ***************************************************************************/

// import { Alert, Button } from 'antd';
import { pickedVertexData } from '@amcax/base';
import { NonDialogPickableCommandForm } from '@app-cad/common/components/command-form/pickable';
import { useCommand } from '@app-cad/common/hooks/useCommand';
import { useTools } from '@app-cad/common/hooks/useTools';
import { useAsyncEffect } from 'ahooks';
import { useEffect, useState } from 'react';
import './index.scss';
import { curveSchema, extraUiCurve, Mode, typeAgs } from './type';
import { Radio } from 'antd';
import { Vector3 } from 'three-legacy';
import { ctx2 } from '@app-base/module';
import { documentV2 } from '@app-nextmesh/domain';
import { createPoint, removePoint } from '../cmd-common/tools';

type Params = {
  points: {
    point: string;
  }[];
};

type FormData = {
  point?: pickedVertexData;
  point1?: number;
  point2?: number;
  point3?: number;
}[];
const defaultItem = {
  point: undefined,
  point1: undefined,
  point2: undefined,
  point3: undefined,
};
export function Curve({ onClose, props }) {
  const [mode, setMode] = useState<Mode.SELECT | Mode.INPUT>(Mode.SELECT);
  const defaultForm = [defaultItem, defaultItem];

  const [formData, setFormData] = useState<FormData>(defaultForm);

  const { picker } = useTools();

  useAsyncEffect(async () => {
    if (props == null) {
      setFormData(defaultForm);
      return;
    }

    const params = props.params as Params;

    setFormData(
      params.points.map((p) => ({
        point: picker.generatePickObjByPickID(p.point) as pickedVertexData,
      })),
    );
  }, [props?.shape]);

  const checkAndFinishDraw = async () => {
    if (formData.length < 2 || formData.some((p) => p?.point == null)) return;

    await execute(false);

    onClose();
  };
  // 释放对象
  const { initingEdit, clear, isLoading, isPreviewLoading } = useCommand(
    'cmd-mesh-curve',
    {
      releaseObjects: removePoint,
      editDxid: props?.shape,
      onClose,
      finishDraw: checkAndFinishDraw,
    },
  );

  const execute = async (preview: boolean) => {
    let source = null;
    if (mode === Mode.SELECT) {
      source = formData.map((p) => p.point.vertexId);
    } else {
      source = formData.map((p) => [p.point1, p.point2, p.point3]);
    }
    try {
      await documentV2.basicCurve({ source, mode: 'curve' }, preview);
    } catch (error) {
      //
    }
  };

  const isFormDataValid = () => {
    if (formData.length < 2) {
      return false;
    }
    if (mode === Mode.SELECT) {
      return formData.every((p) => p?.point != null);
    } else {
      const flag = formData.every(
        (p) => p?.point1 != null && p?.point2 != null && p?.point3 != null,
      );
      return flag;
    }
  };

  const preview = async () => {
    clear();
    if (!isFormDataValid()) {
      return;
    }

    await execute(true);
  };
  useEffect(() => {
    removePoint();
    if (isFormDataValid() && mode === Mode.INPUT) {
      const vertexs = formData.map(
        (p) => new Vector3(p.point1, p.point2, p.point3),
      );
      createPoint(vertexs);
      ctx2.viewer.requestRender();
    }
  }, [formData, mode]);

  return (
    <>
      <Radio.Group
        buttonStyle='solid'
        value={mode}
        className='px-5 w-full'
        onChange={(e) => {
          setMode(e.target.value);
        }}
      >
        {typeAgs.map((item) => (
          <Radio.Button
            className='w-1/2 text-center'
            value={item.value}
          >
            {item.label}
          </Radio.Button>
        ))}
      </Radio.Group>
      <NonDialogPickableCommandForm
        disabled={initingEdit}
        onCancel={onClose}
        schema={curveSchema[mode]}
        onPreview={preview}
        submitLoading={isLoading}
        previewLoading={isPreviewLoading}
        formData={formData}
        onChange={(v) => {
          setFormData(v);
          if (mode === Mode.SELECT) {
            setFormData((state) => {
              return v.map((p, i) => {
                if (p.point == null) {
                  return state[i];
                } else {
                  const vertex = p.point?.assisObj.getVertex();
                  return {
                    ...state[i],
                    point1: vertex.x,
                    point2: vertex.y,
                    point3: vertex.z,
                  };
                }
              });
            });
          }
        }}
        submitText='完成'
        onSubmit={checkAndFinishDraw}
        extraUiSchema={extraUiCurve[mode]}
        isFormDataValid={isFormDataValid()}
      />
    </>
  );
}
